// Advanced flags.  DEBUG shows useful event information, slowing down the program.
// HIDE_FOCUS is another flag meant only for testing, which disables the focus border around the images without having to
// 		specify a custom image for focus.
var DEBUG = true;
var HIDE_FOCUS = false;

			var ie = false;
			/*@cc_on 
				ie = true; 
			@*/

// Namespace: Hanako
if (typeof(Hanako) == "undefined")
	Hanako = function() {}
	
/**		DO RADIO BOXES - FOR RADIO, ONLY ACTUAL EVENTS ARE HANDLED DIFFERENTLY (BY CHECKING ALL IMAGES TO SEE CHECKED STATUS, SINCE ONLY 1 PER GROUP CAN BE CHECKED).
 * Hanako.CheckBox - Replaces all the checkboxes in the page, or all checkboxes with a specified class name to custom images, handling common events.
 * @constructor
 * @author: Alex Melman, Minsc Design
 * @version Development 0.1.5.5 - 6/12/07
 * @requires {Prototype} Prototype Framework 1.5.0
 * @param {object} arg_options - This object contains all of the properties necessary for the functionality of Hanako.Controls.CheckBox.
 *		- List of properties:
 *			1) affectedElements - optional: This is an enumeration of type Hanako.AffectedElements, which contains three values
 *				determining which checkbox objects will be affected by Hanako.CheckBox.  The values are as follows:
 *				a) all - default value: By setting affectedElements to all, all of the checkboxes on the webpage will be modified.
 *				b) byClass: By setting this value, only checkbox elements with the classname specified in property, checkElementName,
 *					will be modified.
 *				c) byId: By setting this value, only the one checkbox element with the ID specified in property, checkElementName,
 *					will be modified.
 *				An example - Setting this property: 
 *					arg_options.affectedElements = Hanako.AffectedElements.byClass;
 *			2) checkElementName - optional: This name is required when the affectedElements property is set to byClass or byId.
 *				When set to byClass, this serves as the class name, and when set to byId, this serves as the ID.
 *			MODIFY---->3) image - required: This is an object of type Hanako.StateImage, which holds image objects for each possible
 *				event state, such as normal, hover, active (pressed), disabled, and focused.  This property only hold images
 *				for the checkbox's checked state.
 **/
Hanako.CheckBox = function(arg_options)
{
	var FULL_NAMESPACE = "Hanako.Controls";
	var FULL_CLASSNAME = FULL_NAMESPACE + ".CheckBox";
	this.getFullNameSpace = function()
	{
		return FULL_NAMESPACE;
	}
	this.getFullClassName = function()
	{
		return FULL_CLASSNAME;
	}
	
	// Properties passed in with arg_options.
	if (!arg_options.checkImage)
	{
		Hanako.Util.throwException(FULL_NAMESPACE + ".CheckBoxException", FULL_CLASSNAME + ".constructor()", 1, "The argument passed into this constructor requires the checkImage property.");
	}
	var m_image = arg_options.checkImage;
	var m_blankImg = arg_options.blankImg;
	var m_testImageSupport = arg_options.testImageSupport ? arg_options.testImageSupport : true;
	var m_affectedElements = arg_options.affectedElements;
	var m_checkElementName = arg_options.checkElementName;
	var m_hoverMode = arg_options.hoverMode ? arg_options.hoverMode : Hanako.HoverMode.none;
	var m_useCustomFocusedImage = arg_options.useCustomFocusedImage;
	var m_disabledOpacity = arg_options.disabledOpacity ? arg_options.disabledOpacity : 50;
	var m_useDisabledOpacity = arg_options.disabledOpacity ? arg_options.disabledOpacity : true;
	var m_imageNamePrefix = arg_options.imageNamePrefix ? argOptions.imageNamePrefix : "md_check_image_";
	var m_debugEventArea = arg_options.debugEventArea;
	var m_eventPollingIntervalSlow = arg_options.eventPollingIntervalSlow ? arg_options.eventPollingIntervalSlow : 800;
	var m_eventPollingIntervalFast = arg_options.eventPollingIntervalFast ? arg_options.eventPollingIntervalFast : 100;
		
	var m_inputs = new Array();
	var m_tabIndexes = new Array();
	var m_openInputIndexes = new Array();
	var m_focusedElement;
	var m_mouseDown;
	
	/**
	 * Hanako.CheckBox.setImages - Sets the image files used for the checkboxes.
 	 * @public
	 * @method
	 * @author Alex Melman, Minsc Design
	 * @param {Hanako.StateImages} imagesTrue - The Hanako.StateImages contains the images to be used for each checked state: 
	 *		Hover, Active, None
	 * @param {Hanako.StateImages} imagesFalse - The Hanako.StateImages contains the images to be used for each unchecked state: 
	 *		Hover, Active, None
 	 **/
	var setImage = function(image, blankImg)
	{
		// Check for a property of Hanako.StateImage in member variable or argument to see if image is an instance.  Throw an exception if not.
		if ((!image || !image.image) && (!m_image || !m_image.image))
			Hanako.Util.throwException(FULL_NAMESPACE + ".CheckBoxException", FULL_CLASSNAME + ".setImage()", 1, "An instance of Hanako.StateImage must be passed into this function.");
		
		if (blankImg && !m_blankImg)
			m_blankImg = new Image(blankImg);
		// TODO: Put image checking functionality or link to blank image outside class.
			
		// Check if the Hanako.StateImage instance is the same as the one stored in the member variable.  If not, then reset the checkboxes.
		if (image)
		{
			if (m_image !== image)
				resetImage();
			m_image = image;
		}
		imagesEnabled();
	}
	
	var resetImage = function()
	{
		// TO IMPLEMENT.
	}
	
	this.setDisabledOpacity = function(opacity)
	{
		if (opacity >= 0 && opacity <= 100)
		{
			m_disabledOpacity = opacity;
			return true;
		}
		return false;
	}
	
	/**
	 * Hanako.CheckBox.imagesEnabled - Tests a blank image to see if images are enabled.  
	 * 		Waits for the image to load (asynchronously) before changing the checkboxes.
	 *  	Original function name: so_checkCanCreate, from http://www.slayeroffice.com.
	 * @author: Steve Chipman, slayeroffice.
	 **/
	var imagesEnabled = function()
	{
		if (m_testImageSupport)
		{
			var testImage = document.body.appendChild(document.createElement("img"));
			testImage.onload = imagesEnabledFinish;
			// MSIE will cache the test image, causing it to not fire the onload event the next time the
			// page is hit. The parameter on the end will prevent caching.
			testImage.src = "images/blank.gif?" + new Date().valueOf();
			testImage.id = "so_testImage";
		}
		else
		{
			imagesEnabledFinish();
		}
	}
	
	/**
	 * Private Method: Hanako.CheckBox.imagesEnabledFinish
	 * Description: This is an event handler that gets called only after the test image used in the imagesEnabled
	 *		function has loaded.  This function loads replaceChecks, which proceeds to create the custom checkboxes.
	 **/
	var imagesEnabledFinish = function()
	{
		replaceChecks(m_checkElementName);
	}
	
	/**
	 * Private Method: Hanako.CheckBox.replaceChecks
	 * Description: This function does the actual work of replacing the checkboxes and setting up the events
	 *		using the images specified in the member variables.
	 * Param - checkElementName: Specifies a name so that only checkbox objects with the specified class name will be affected.
	 **/
	var replaceChecks = function(checkElementName)
	{
		m_checkElementName = checkElementName;
		if (checkElementName && checkElementName.length > 0)
		{
			// Get only inputs fields with the specified class name.
			var i = 0, j = 0;
			var inputs = new Array();
			var tagInputs = document.getElementsByTagName("input");
			for (i = 0; i < tagInputs.length; i++)
			{
				if (YAHOO.util.Dom.hasClass(tagInputs[i], checkElementName))
				{
					inputs[j] = tagInputs[i];
					j++;
				}
			}
		}
		else
		{
	    	// Get all the input fields on the page.
	    	inputs = document.getElementsByTagName('input');
    	}
    
	    //cycle through the input fields
	    for (var i = 0; i < inputs.length; i++) 
	    {
			setCustomCheckbox(inputs[i]);
	    }
	}
	
	/* TO IMPLEMENT AFTER RELEASE */
	/*this.unsetCustomCheckbox = function(elem)
	{
		if (elem.getAttribute("type") == "checkbox")
		{
			for (var i = 0; i < m_inputs.length; i++)
			{
				if (m_inputs[i].id == elem.id)
				{
					m_openInputIndexes[m_openInputIndices.length] = i;
					elem.parent.removeChild(getImageElemFromCheckbox(m_imageNamePrefix + index));	// Remove Image.
					elem.style.postion = "relative";
					elem.tabIndex = m_tabIndexes[i];
					m_tabIndexes[i] = null;
				}
			}
		}
	}*/				
	
	var setCustomCheckbox = function(elem)
	{
		var index = -1;
		
		//check if the input is a checkbox
		if (elem.getAttribute('type') == 'checkbox')
		{
			for (var i = 0; i < m_inputs.length; i++)
			{
				if (m_inputs[i] == elem)
				{
					index = i;
				}
			}
			if (index < 0)
			{
				// Append new input to end of array.
				index = m_inputs.length;
				m_inputs[index] = elem;

				// Probably not needed:
				//elem.addClassName(m_imageNamePrefix + index);
				
				// Hide the checkbox
				//if (elem.style.display != "none")
				//	elem.style.display = "none";
	
				elem.style.position = "absolute";
				elem.style.zIndex = "-1";

				if (navigator.userAgent.toLowerCase().indexOf("safari") >= 0)
				{
					Hanako.Util.setOpacity(elem, 0);
				}
				else
				{
					elem.style.left = "-5000px";
					m_tabIndexes[index] = elem.tabIndex;
					elem.tabIndex = "-1";
				}
				
				// Create a new image
				var img = document.createElement('img');
				img.src = "./images/blank.gif";
				img.style.backgroundImage = "url(" + m_image.image + ")";
				img.style.backgroundRepeat = "no-repeat";
				img.style.width = m_image.width + "px";
				img.style.height = m_image.height + "px";
				img.style.verticalAlign = "-10%";
	
				//check if the checkbox is checked
				if(elem.checked) 
				{
					img.style.backgroundPosition = m_image.getOffsetNormalT().toString();
				} 
				else 
				{
					img.style.backgroundPosition = m_image.getOffsetNormalF().toString();
				}
				
				// If the checkbox object is disabled, then "disable" the image.
				if (elem.disabled)
				{
					img.tabIndex = "-1";
					Hanako.Util.setOpacity(img, m_disabledOpacity);
				}
				else
				{
					img.tabIndex = m_tabIndexes[index];
					Hanako.Util.setOpacity(img, 100);
				}
	
				// Set image ID and basic properties.
				img.id = m_imageNamePrefix + index;
				YAHOO.util.Dom.addClass(img, m_imageNamePrefix);
				
				unsetDraggable(img);
	
				// Set image event handlers
				YAHOO.util.Event.addListener(img, "keyup", checkKeyUp);
				YAHOO.util.Event.addListener(img, "keydown", checkKeyDown);
				YAHOO.util.Event.addListener(img, "click", checkClick);
				YAHOO.util.Event.addListener(img, "dblclick", checkDblClick);
				YAHOO.util.Event.addListener(img, "mouseover", checkOver);
				YAHOO.util.Event.addListener(img, "mouseout", checkOut);
				YAHOO.util.Event.addListener(img, "mousedown", checkMouseDown);
				YAHOO.util.Event.addListener(img, "mouseup", checkMouseUp);
				YAHOO.util.Event.addListener(img, "focus", checkFocus);
				YAHOO.util.Event.addListener(img, "blur", checkBlur);
				
				YAHOO.util.Event.addListener(elem, "keyup", checkKeyUp);
				YAHOO.util.Event.addListener(elem, "focus", checkFocus);
				YAHOO.util.Event.addListener(elem, "change", checkChange);
		
				//place image before the checkbox
				elem.parentNode.insertBefore(img, elem.nextSibling);
				
				window.setInterval(pollEvents, m_eventPollingIntervalSlow);
			}
			else
			{
				// Do limited set of functions for existing checkbox.
			}
		}
	}
	
	var pollEvents = function()
	{
		//updateIndexedCheckboxItems();
		updateDisabledImages();
	}
	
	var unsetDraggable = function(elem)
	{
		elem.style["-khtml-user-drag"] = "none";			// For KHTML.
		YAHOO.util.Event.addListener(elem, "draggesture", checkDrag);		// Sets up event for FF.
		YAHOO.util.Event.addListener(elem, "drag", checkDrag);				// Sets up event for IE.
	}
	
	// Public function wrapper for private function of same name.
	/*this.updateIndexedCheckboxItems = function()
	{
		updateIndexedCheckboxItems();
	}
	var updateIndexedCheckboxItems = function()
	{
		var tagInputs = YAHOO.util.Dom.getElementsByClassName(m_checkElementName, "input");

		// If there are more or less inputs detected that use custom checkbox images, then set up the checkboxes again.
		if (tagInputs.length != m_inputs.length)	
		{
			removeChecks();
			replaceChecks();
		
		m_inputs = tagInputs;
	}*/
	
	// Public function wrapper for private function of same name.
	this.updateDisabledImages = function()
	{
		updateDisabledImages();
	}
	/**
	 * Hanako.CheckBox.toggleImgDisabled - Toggles whether a checkbox element is disabled.
	 * @author Alex Melman, Minsc Design
	 * @param {string} id - The id of the checkbox element to enable/disable.
	 **/
	var updateDisabledImages = function()
	{
		var checkboxElem;
		var imageElems = YAHOO.util.Dom.getElementsByClassName(m_imageNamePrefix, "img");
		
		for (var i = 0; i < imageElems.length; i++)
		{
			checkboxElem = getCheckboxElemFromImage(imageElems[i]);
			
			if (checkboxElem.disabled)
			{
				Hanako.Util.setOpacity(imageElems[i], m_disabledOpacity);
				imageElems[i].tabIndex = "-1";
			}
			else
			{
				Hanako.Util.setOpacity(imageElems[i], 100);
				imageElems[i].tabIndex = m_tabIndexes[i];
			}
		}
	}
	
		// ???KEEP TRACK OF WHICH ITEMS HAVE FOCUS MANUALLY.
	var getCheckboxElemFromImage = function(elem)
	{
		var index = getCheckboxIndex(elem);
		if (index < 0)
			return null;
		
		return m_inputs[index];
	}
	
	var getCheckboxElemFromLabel = function(elem)
	{
		var forElemName = elem.getAttribute("for");
		if (forElemName)
		{
			return document.getElementById(forElemName);
		}
		return null;
	}	
	
	var getCheckboxIndex = function(elem)
	{
		return parseInt(elem.id.substring(m_imageNamePrefix.length));
	}
	
	var getImageElemFromCheckbox = function(elem)
	{
		var index;
		
		for (var i = 0; i < m_inputs.length; i++)
		{
			if (m_inputs[i].id == elem.id)
			{
				index = i;
				break;
			}
		}
 
 		if (index)
 		{
			var image = document.getElementById(m_imageNamePrefix + index);
			return image ? image : null;
		}
		else
			return null;
	}
	
	/* TODO: PUT IN SEPARATE CLASS?? */
	var outputEventMessage = function(message)
	{
		var time = new Date();
		
		if (DEBUG)
		{
			console.info(leadingZero(time.getHours()) + ":" + leadingZero(time.getMinutes()) + ":" + 
				leadingZero(time.getSeconds()) + " - " + message + "\n");
		}
	}
	
	var leadingZero = function(num)
	{
		if (num < 10) num = "0" + num;
		return num;
	}
	
	// This function improves perfomance in IE, since double-clicks take precedence over regular clicks.
	// In FF, regular clicks have precedence, so there is no problem.
	// Note: The code to call the click event is enclosed in an IE only conditional comment.
	// Yes, this is a form of browser sniffing (for IE), but in this case, browser sniffing is the only way to
	// deal with this particular problem, since there is no test for it.
	var checkDblClick = function(e)
	{
		outputEventMessage("Image Double-Click");

		/*@cc_on
			checkClick(e);
		@*/
	}
	
	var checkFocus = function(e)
	{
		var elem, checkbox;
		elem = YAHOO.util.Event.getTarget(e);
		
		if (elem)
		{
			if (elem.tagName.toLowerCase() == "img")
			{
				outputEventMessage("Image Focus: " + elem.id);
			
				if ((m_useCustomFocusedImage || elem.disabled) || HIDE_FOCUS)
				{
					elem.hideFocus = true;				// For IE
					elem.style.outline = "none";		// For FF
				}
				
				m_focusedElement = elem;
				
				// Make sure disabled checkboxes are accounted for before continuing.
				if (m_mouseDown)
				{
					m_mouseDown = false;
					return;
				}
				
				if (m_useCustomFocusedImage)
				{				
					checkbox = getCheckboxElemFromImage(elem);
					if (checkbox)
					{
						if (!checkbox.disabled)
						{		
							if(checkbox.checked) 
							{
								elem.style.backgroundPosition = m_image.getOffsetHoverT().toString();
							}
							else 
							{
								elem.style.backgroundPosition = m_image.getOffsetHoverF().toString();
							}
						}
					}
				}
			}
			else if (elem.tagName.toLowerCase() == "input" && elem.type.toLowerCase() == "checkbox")
			{
				outputEventMessage("Checkbox Focus: " + elem.id);
					
				var imageElem = getImageElemFromCheckbox(elem);
				/*if (imageElem)
				{
					if (elem.checked)
					{
						imageElem.style.backgroundPosition = m_image.getOffsetHoverT().toString();
					}
					else
					{
						imageElem.style.backgroundPosition = m_image.getOffsetHoverF().toString();
					}
				}*/
				if (imageElem)
					imageElem.focus();
			}
		}
	}
	
	var checkBlur = function(e)
	{
		var elem = YAHOO.util.Event.getTarget(e);
			
		if (!m_useCustomFocusedImage)
			return;

		if (elem)
		{
			if (elem.tagName.toLowerCase() == "img")
			{
				outputEventMessage("Image Blur: " + elem.id);
			
				var checkboxElem = getCheckboxElemFromImage(elem);
				if (checkboxElem)
				{
					if(checkboxElem.checked) 
					{
						elem.style.backgroundPosition = m_image.getOffsetNormalT().toString();
					}
					else 
					{
						elem.style.backgroundPosition = m_image.getOffsetNormalF().toString();
					}
					
					m_focusedElement = null;
				}
			}
		}
	}
		
	var checkChange = function(e)
	{		
		var elem, checkbox, imgId, i;
		var img = new Image();
		elem = YAHOO.util.Event.getTarget(e);
		
		outputEventMessage("Check Change: " + elem.id);
		
		if (elem && elem.tagName.toLowerCase() == "input")
		{
			for (i = 0; i < m_inputs.length; i++)
			{
				if (m_inputs[i].id == elem.id)
				{
					checkbox = elem;
					break;
				}
			}
			
			if (checkbox.disabled)
			{
				Hanako.Util.setOpacity(checkbox, m_disabledOpacity);
				return;
			}
			else
			{
				Hanako.Util.setOpacity(checkbox, 100);
			}

			img = getImageElemFromCheckbox(elem);
			
			//check if the checkbox is checked
		
			if (img)
			{
				if(checkbox.checked) 
				{
					img.style.backgroundPosition = m_image.getOffsetNormalT().toString();
				} 
				else 
				{
					img.style.backgroundPosition = m_image.getOffsetNormalF().toString();
				}
				img.focus();
				
				m_focusedElement = elem;
			}
		}
	}
	
	var checkKeyDown = function(e)
	{		
		var elem, index;
		elem = YAHOO.util.Event.getTarget(e);
		
		outputEventMessage("Image Key Down: " + elem.id);
			
		if (m_hoverMode != Hanako.HoverMode.active)
			return;
			
		if (elem && elem.tagName.toLowerCase() == "img")
		{
			if (elem && (e.keyCode == 32 || e.which == 32))		// 32 = Space Key
			{	
				m_focusedElement = elem;
				
				//checkbox = getCheckboxElemFromImage(elem);
				//if (checkbox)
					//checkbox.focus();
				
				setChecked(elem, false, false, Hanako.HoverMode.active);
			}
		}
	}
	
	var checkKeyUp = function(e)
	{
		var elem, index;
		elem = YAHOO.util.Event.getTarget(e);
		
		if (elem && (e.keyCode == 32 || e.which == 32))		// 32 = Space Key
		{	
			// In IE, when the label is clicked, the checkbox click event is activated.
			// In FF, when the label is clicked, the image click event gets activated.  Label never takes focus.  Find out why.
			if (elem.tagName.toLowerCase() == "img")
			{	
				outputEventMessage("Image Key Up: " + elem.id);
					
				setChecked(elem, true, false, Hanako.HoverMode.hover);
				m_focusedElement = elem;

			 	var checkboxElem = getCheckboxElemFromImage(elem);
				checkboxElem.click();
			}
			else if (elem.tagName.toLowerCase() == "input" && elem.type.toLowerCase() == "checkbox")
			{
				outputEventMessage("Checkbox Key Up: " + elem.id);
			
				var imageElem = getImageElemFromCheckbox(elem)
				setChecked(imageElem, true, false, Hanako.HoverMode.hover);
			}
		}
	}
	
	var setChecked = function(elem, toggleImg, toggleCheckbox, hoverMode)
	{
		var checkboxElem;
		
		if (elem && elem.tagName.toLowerCase() == "img")
		{
			checkboxElem = getCheckboxElemFromImage(elem);
			
			if (checkboxElem.disabled)
			{
				Hanako.Util.setOpacity(elem, m_disabledOpacity);
				return;
			}
			else
			{
				Hanako.Util.setOpacity(elem, 100);
			}

			if (m_hoverMode != Hanako.HoverMode.none && hoverMode == Hanako.HoverMode.active)
			{
				if(checkboxElem.checked) 
				{
					elem.style.backgroundPosition = m_image.getOffsetActiveT().toString();
				}
				else 
				{
					elem.style.backgroundPosition = m_image.getOffsetActiveF().toString();
				}
			}
			else if ((elem == m_focusedElement && m_useCustomFocusedImage) || (m_hoverMode != Hanako.HoverMode.none && hoverMode == Hanako.HoverMode.hover))
			{
				if(checkboxElem.checked) 
				{
					elem.style.backgroundPosition = toggleImg ? m_image.getOffsetHoverF().toString() : m_image.getOffsetHoverT().toString();
					checkboxElem.checked = toggleCheckbox ? '' : 'checked';
				}
				else 
				{
					elem.style.backgroundPosition = toggleImg ? m_image.getOffsetHoverT().toString() : m_image.getOffsetHoverF().toString();
					checkboxElem.checked = toggleCheckbox ? 'checked' : '';
				}
			}
			else
			{
				if(checkboxElem.checked) 
				{
					elem.style.backgroundPosition = toggleImg ? m_image.getOffsetNormalF().toString() : m_image.getOffsetNormalT().toString();
					checkboxElem.checked = toggleCheckbox ? '' : 'checked';
				}
				else 
				{
					elem.style.backgroundPosition = toggleImg ? m_image.getOffsetNormalT().toString() : m_image.getOffsetNormalF().toString();
					checkboxElem.checked = toggleCheckbox ? 'checked' : '';
				}
			}
		}
	}
	
	var checkClick = function(e) 
	{			
		var elem = YAHOO.util.Event.getTarget(e);
		
		outputEventMessage("Image Mouse Click: " + elem.id);
		
		setChecked(elem, true, false, Hanako.HoverMode.none);
		
		var checkboxElem = getCheckboxElemFromImage(elem);
		checkboxElem.click();
	}
	
	// Check for mouse movement here instead of mousemove.
	var checkMouseDown = function(e)
	{		
		var elem = YAHOO.util.Event.getTarget(e);
	
		outputEventMessage("Image Mouse Down: " + elem.id);

		if (m_hoverMode != Hanako.HoverMode.active)
			return;
			
		m_mouseDown = true;
		setChecked(elem, false, false, Hanako.HoverMode.active);
	}
	
	var checkMouseUp = function(e)
	{
		outputEventMessage("Image Mouse Up: " + YAHOO.util.Event.getTarget(e));
			
		m_mouseDown = false;
		// Do nothing.  MouseClick handles this.
	}
	
	// Prevents dragging of the checkbox image.
	var checkDrag = function(e)
	{			
		var elem = YAHOO.util.Event.getTarget(e);
		
		outputEventMessage("Image Mouse Drag: " + elem.id);
		
		if (elem && elem.tagName.toLowerCase() == "img")
		{
			/*@cc_on
				e.returnValue = false;
				return false;
			@*/

			e.preventDefault();
			return false;
		}
	}
	
	var checkOver = function(e)
	{
		var elem, index;
		elem = YAHOO.util.Event.getTarget(e);
		
		outputEventMessage("Image Mouse Over: " + elem.id);
			
		if (m_hoverMode == Hanako.HoverMode.none)
			return;
	
		setChecked(elem, false, false, Hanako.HoverMode.hover);
	}
	
	var checkOut = function(e)
	{			
		var elem, index;
		elem = YAHOO.util.Event.getTarget(e);
		
		outputEventMessage("Image Mouse Out: " + elem.id);
			
		if (m_hoverMode == Hanako.HoverMode.none)
			return;
	
		setChecked(elem, false, false, Hanako.HoverMode.none);
	}
	
	var init = function()
	{
		setImage(m_image, m_blankImg);
	}
	
	init();	
}

Hanako.StateImage = function(image, width, height)
{
	this.setImage = function(image, width, height)
	{
		if (!image || !width || !height)	// All arguments are required.
		{
			Hanako.Util.throwException("Hanako.Controls.StateImageException", "Hanako.Controls.StateImage.setImage()", 1, "All arguments are required.");
		}
		this.image = image;		// The path string to the image.
		this.width = width;		// The width in pixels of individual sections of the image.
		this.height = height; 	// The height in pixels of individual sections of the image.
	}
	
	// The image must be shifted left and up.  Thus, the negative values.
	this.getOffsetNormalF= function()			// (0,0)
	{
		return new Hanako.Offset(0, 0);
	}
	this.getOffsetHoverF = function()			// (-1,0)
	{
		return new Hanako.Offset(0 - this.width, 0);
	}
	this.getOffsetActiveF = function()			// (-2,0)
	{
		return new Hanako.Offset(0 - this.width * 2, 0);
	}
	this.getOffsetDisabledF= function()			// (-3,0)
	{
		return new Hanako.Offset(0 - this.width * 3, 0);
	}
	this.getOffsetNormalT = function()			// (0,-1)
	{
		return new Hanako.Offset(0, 0 - this.height);
	}
	this.getOffsetHoverT = function()			// (-1,-1)
	{
		return new Hanako.Offset(0 - this.width, 0 - this.height);
	}
	this.getOffsetActiveT = function()			// (-2,-1)
	{
		return new Hanako.Offset(0 - this.width * 2, 0 - this.height);
	}
	this.getOffsetDisabledT = function()		// (-3,-1)
	{
		return new Hanako.Offset(0 - this.width * 3, 0 - this.height);
	}
	
	this.setImage(image, width, height);
}

Hanako.Offset = function(x, y)
{
	this.x = x;
	this.y = y;
	
	this.toString = function()
	{
		return this.x + "px " + this.y + "px";
	}
}
	
/**
 * Hanako.Controls.StateImages - A structure to hold the images used by Hanako controls.
 * @author Alex Melman
 * @param {string} normal - A path name leading to the image used when there is no hover or active button press.
 * @param {string} hover - A path name leading to the image used when there is currently a hover event.
 * @param {string} active = A path name leading to the image used when there is currently an active button press event.
 **/
 /*
if (typeof(Hanako.StateImages) == "undefined")
{
	Hanako.StateImages = function(normal, hover, active, disabled)
	{
		this.normal = new Image();
		this.hover = new Image();
		this.active = new Image();
		this.disabled = new Image();
		this.width;
		this.height;
	
		/**
		 * Hanako.StateImages.setImages - Sets the images in the structure to the path names given as parameters.
		 * @param {string} normal - A path name leading to the image used when there is no hover or active button press.
		 * @param {string} hover - A path name leading to the image used when there is currently a hover event.
		 * @param {string} active = A path name leading to the image used when there is currently an active button press event.
		 ****
		this.setImages = function(normal, hover, active, disabled)
		{
			this.normal.src = normal;
			this.hover.src = hover;
			this.active.src = active;
			this.disabled.src = disabled;
		}
		
		this.setSize = function(width, height)
		{
			if (!width || !height)
			{
				this.width = null;
				this.height = null;
			}
			else
			{
				this.width = width;
				this.height = height;
			}
		}
		
		this.setImages(normal, hover, active, disabled);
	}
}*/
	

/**
 * Hanako.AffectedElements - An enumeration class containing values, which determine which elements are
 * affected by a procedure.
 * @author Alex Melman
 **/
Hanako.AffectedElements = function()
{
}
/**
 * All elements (of the type affected by the procedure) are affected.
 **/
Hanako.AffectedElements.all = 0;
/**
 * Only elements (of the type affected by the procedure) with a specific class name are affected by the procedure.
 **/
Hanako.AffectedElements.byClass = 1;
/**
 * Only the element with a given ID is affected by the procedure.
 **/
Hanako.AffectedElements.byId = 2;

/**
 * Hanako.HoverMode - An enumeration class containing values, which determine whether hover and/or
 *		active button press events will be used.
 * @author Alex Melman
 **/
Hanako.HoverMode = function()
{
}
/**
 * No hover or active button press events.
 * @public
 * @final
 **/
Hanako.HoverMode.none = 0;
/**
 * Hover events enabled.
 * @public
 * @final
 **/
Hanako.HoverMode.hover = 1;
/**
 * Hover and active button press events enabled.
 * @public
 * @final
 **/
Hanako.HoverMode.active = 2;

if (typeof(Hanako.Util) == "undefined")
	Hanako.Util = function() {}

/**
 * Hanako.Util.setOpacity - A simple cross-browser function to set an element's opacity.
 * Note: The element must have layout.
 * @param {object} elem - The element which will change opacity.
 * @param {integer} value - A percentage value specifying the element's opacity.
 **/
Hanako.Util.setOpacity = function(elem, value) 
{
	elem.style.KHTMLopacity = value / 100;
	elem.style.opacity = value / 100;
	elem.style.filter = "alpha(opacity= " + value + ")";
}

Hanako.Util.throwException = function(exceptionName, functionName, number, message)
{
	var exception = new Error(message);
	exception.name = exceptionName;
	exception.number = number;
	if (DEBUG)
		alert("An exception has occured in function " + functionName + ":\n\n" + exception.message + "\n\nCheck your browser's " +
			  "error message for more details.");
	throw exception;
}

Hanako.Util.toEms = function(parentElem, px)
{
	if (typeof(px) == "string")
		px = px.replace(/\D+/, "");
		
	var md_one_em = document.getElementById("md_one_em");
	if (!md_one_em)
	{
		md_one_em = document.createElement("div");
		parentElem.appendChild(md_one_em);
	}

	md_one_em.style.width = "1em";
	
	//var value = (px / md_one_em.getCoordinates().height) + "em";
	var value = (px / md_one_em.getDimensions().width) + "em";
	parentElem.removeChild(md_one_em);
	return value;
}
